home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / util / bsindex1 / part01 / src / sort.c < prev    next >
C/C++ Source or Header  |  1990-02-02  |  4KB  |  148 lines

  1. /*
  2.  * SORT.C
  3.  *
  4.  * This module contains the sorting routines that read sorting order from
  5.  * the command line, and sort the file database according to that order.
  6.  *
  7.  */
  8.  
  9. #ifndef LATTICE_50
  10. #include "system.h"
  11. #endif
  12.  
  13. #include "bbsindex.h"
  14.  
  15.  
  16. /*
  17.  *        Arrays used to determine sorting order for SORT.
  18.  */
  19.  
  20. int i_order[MAXINDEX+1];
  21. int i_ascend[MAXINDEX+1];
  22.  
  23.  
  24. /*
  25.  *        sortcmp()
  26.  *        ---------
  27.  *        This function is called by qsort. It compares the two specified
  28.  *        elements, and returns -ve, 0 or +ve to indicate whether the second
  29.  *        record is greater than, equal or less than the first, using the
  30.  *        sorting criteria defined in SORT.
  31.  */
  32.  
  33. /*
  34.  *        DOCMP is a macro which sets cmp equal to the value of the enclosed
  35.  *        expression if i_ascend[i] is true, or the negative of the expression
  36.  *        if i_ascend is false.
  37.  */
  38. #define DOCMP(x)    (cmp = (i_ascend[i] ? (x) : -(x)))
  39. int sortcmp(ptr1,ptr2)
  40. UDHEAD **ptr1, **ptr2;
  41. {
  42.     UDHEAD *p1 = *ptr1, *p2 = *ptr2;
  43.     int i, cmp = 0;
  44.  
  45.     /*
  46.      *        Note safety exit - last element of i_order is guaranteed == I_ANY
  47.      */
  48.     for (i = 0; !cmp; i++) {
  49.         switch (i_order[i]) {
  50.  
  51.             case I_ANY:            return(0);
  52.  
  53.             case I_ACCESS:        DOCMP(p1->accesses - p2->accesses);
  54.                                 break;
  55.             case I_BINARY:        DOCMP(p2->bin - p1->bin);
  56.                                 break;
  57.             case I_COMMENT:        DOCMP(stricmp(p1->desc, p2->desc));
  58.                                 break;
  59.             case I_DISKNAME:    DOCMP(stricmp(p1->disk_name, p2->disk_name));
  60.                                 break;
  61.             case I_SECTION:        DOCMP(p1->section - p2->section);
  62.                                 break;
  63.             case I_ONLINE:        DOCMP(p2->online - p1->online);
  64.                                 break;
  65.             case I_LOCAL:        DOCMP(p2->local - p1->local);
  66.                                 break;
  67.             case I_NAME:        DOCMP(strcmp(p1->cat_name, p2->cat_name));
  68.                                 break;
  69.             case I_OWNER:        DOCMP(strcmp(p1->owner, p2->owner));
  70.                                 break;
  71.             case I_PATHNAME:    DOCMP(strcmp(dirnames[p1->dirnum],
  72.                                              dirnames[p2->dirnum]));
  73.                                 break;
  74.             case I_DIRECTORY:    DOCMP(p1->dir - p2->dir);
  75.                                 break;
  76.             case I_DISKDIRNUM:    DOCMP(p1->dirnum - p2->dirnum);
  77.                                 break;
  78.             case I_VALID:        DOCMP(p2->valid - p1->valid);
  79.                                 break;
  80.             case I_DATE:        DOCMP(p1->date - p2->date);
  81.                                 break;
  82.             case I_SIZE:        DOCMP(p1->length - p2->length);
  83.                                 break;
  84.             case I_KSIZE:        DOCMP(BTOK(p1->length) - BTOK(p2->length));
  85.                                 break;
  86.         }
  87.     }
  88.     return (cmp);
  89. }
  90.  
  91.  
  92. /*
  93.  *        com_sort()
  94.  *        ----------
  95.  *        This command sorts the file database into order, according to
  96.  *        the indexes specified. Each index may be optionally followed by
  97.  *        a + or - to indirect sorting direction (ascending or descending).
  98.  *        There must be no space between the direction and the +/-.
  99.  */
  100. void com_sort()
  101. {
  102.     char *index, *p;
  103.     int i, j;
  104.     int ascend;
  105.  
  106.     CHECKDATABASE();
  107.  
  108.     sorted = TRUE;
  109.     for (i = 0; i < MAXINDEX && compos < comlen; i++) {
  110.         index = getstring();
  111.         p = index + strlen(index) - 1;
  112.  
  113.         /*
  114.          *        Now check to see if sorting direction specified, and adjust
  115.          *        string if it was. Set 'ascend' to TRUE if ascending,
  116.          *        else FALSE.
  117.          */
  118.         ascend = TRUE;
  119.         if (*p == CHAR_ASCEND || *p == CHAR_DESCEND) {
  120.             if (*p == CHAR_DESCEND)
  121.                 ascend = FALSE;
  122.             *p = CHAR_NULL;
  123.         }
  124.  
  125.         /*
  126.          *        Now match index, and setup appropriate entry in array
  127.          */
  128.  
  129.         for (j = 0; j < MAXINDEX && strcmp(index,indexes[j].name); j++)
  130.             ;
  131.         if (j == MAXINDEX) {
  132.             scripterror("unknown index ");
  133.             print2(index, "\n");
  134.             Cleanup(10);
  135.         }
  136.         i_order[i]    = indexes[j].tag;
  137.         i_ascend[i]    = ascend;
  138.     }
  139.     if (i == 0) {
  140.         i_order[i] = I_NAME;
  141.         i_ascend[i++] = TRUE;
  142.     }
  143.     i_order[i] = I_ANY;
  144.  
  145.     /* Finally, do the sort! */
  146.     qsort(ptrblock, numrecs, sizeof(UDHEAD *), sortcmp);
  147. }
  148.